package com.magima.core.app;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Stack;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Service;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import com.magima.core.basic.Collection;

public abstract class BaseApplication extends Application {
	public static final String KEY_FORCE_UPDATE = "force_update";
	
	public interface ActivityNotFoundExceptionHandler {
		public void onException( Context context, ActivityNotFoundException e);
	}
	
	private ActivityNotFoundExceptionHandler activityNotFoundExceptionHandler;
	
	private Stack<Activity> activityStack = new Stack<Activity>();
	
	private boolean mIAmDeadSignal = true;
	private boolean mDeadHandled = false;
	private HashMap<String, Object> data = new HashMap<String, Object>();//for global data temp repository
	private HashMap<String, Collection<?>> collections = new HashMap<String, Collection<?>>();
	
	public void setAlive(boolean alive){
		mIAmDeadSignal = !alive;
	}
	
	public boolean getAlive(){
		return !mIAmDeadSignal;
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	public boolean isDead(){
		if ( mIAmDeadSignal ) {
			if ( !mDeadHandled ) {
				Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
				i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK|
						(android.os.Build.VERSION.SDK_INT <  android.os.Build.VERSION_CODES.HONEYCOMB 
								? 0 : Intent.FLAG_ACTIVITY_CLEAR_TASK));
				startActivity(i);
				mDeadHandled = true;
			}
		}
		return mIAmDeadSignal;
	}
	
	public void clear() {
		data.clear();
		for (Entry<String, Collection<?>> entry: collections.entrySet()) {
			entry.getValue().removeAllListener();
		}
		collections.clear();
	}
	
	public HashMap<String, Object> getData() {
		return data;
	}
	
	public Collection<?> getCollection(String name){
		return collections.get(name);
	}
	
	public void setCollection(String name, Collection<?> collection){
		collections.put(name, collection);
	}
	
	public static BaseApplication fromContext(Context context){
		if ( context instanceof BaseApplication )
			return (BaseApplication)context;
		if ( context instanceof Activity )
			return (BaseApplication)((Activity)context).getApplication();
		if ( context instanceof Service )
			return (BaseApplication)((Service)context).getApplication();
        Context c = context.getApplicationContext();
        if ( c instanceof BaseApplication )
            return (BaseApplication)c;
		return null;
	}
	
	/**
	 * activity入栈
	 * @param activity
	 */
	public void pushActivity(Activity activity) {
		if(activity != null){
			activityStack.add(activity);
//			Log.e("-----------------", "push : " + activity.getClass() + ", size = " + activityStack.size());
		}
	}
	
	/**
	 * activity出栈
	 * @param activity
	 */
	public void popActivity(Activity activity){
		if(activity != null && activityStack.contains(activity)){
			activityStack.remove(activity);
//			Log.e("-----------------", "pop : " + activity.getClass() + ", size = " + activityStack.size());
			activity = null;
		}
	}

	/**
	 * 主动清空堆栈
	 */
	public void clearActivitys() {
		while(!activityStack.isEmpty()){
			Activity activity = activityStack.firstElement();
			if ( activity != null ){
				activity.finish();
				popActivity(activity);
			}
		}
//		Log.e("-----------------", "clearActivitys, size = " + activityStack.size());
	}
	
    /**
     * 主动清空堆栈，保留栈顶
     */
	public void clearActivitysExceptTop() {
		while(activityStack.size() > 1){
			Activity activity = activityStack.firstElement();
			if ( activity != null ){
				activity.finish();
				popActivity(activity);
			}
		}
	}

	/**
	 * 主动从栈底开始清栈，直到cls（保留cls）
	 * @param cls
	 */
	public void clearActivitysFromButtomUntilClass(Class<?> cls){
		while(activityStack.size() > 0){
			Activity activity = activityStack.firstElement();
			if(activity != null){
				if(activity.getClass() != cls){
					activity.finish();
					popActivity(activity);
				}else{
					break;
				}
			}else{
				continue;
			}
		}
//		Log.e("-----------------", "clearActivitysExceptClass, size = " + activityStack.size());
	}
	
	/**
	 * 主动清空堆栈，保留目标
	 */
	public void clearActivitysExceptClass(Class<?>... clses) {
		Stack<Activity> tempStack = new Stack<Activity>();
		while(!activityStack.isEmpty()){
			Activity activity = activityStack.pop();
			if(activity != null){
				if(inClassList(clses, activity.getClass())){ //是保留目标
					tempStack.push(activity);
				}else{
					activity.finish();
					activity = null;
				}
			}
		}
		
		while(!tempStack.isEmpty()){
			activityStack.push(tempStack.pop());
		}
//		Log.e("-----------------", "clearActivitysExceptClass, size = " + activityStack.size());
	}
	
	private boolean inClassList(Class<?>[] clses, Class<?> cls){
		for(Class<?> c : clses){
			if(c == cls){
				return true;
			}
		}
		return false;
	}
	
	public void setActivityNotFoundExceptionHandler(ActivityNotFoundExceptionHandler handler){
		activityNotFoundExceptionHandler = handler;
	}
	
	public ActivityNotFoundExceptionHandler getActivityNotFoundExceptionHandler(){
		return activityNotFoundExceptionHandler;
	}
	
	public abstract IPromptManager getPromptManager();
	public abstract IExceptionManager getExceptionManager();
	public abstract IAnalystsTool getAnalystsTool();
	public abstract IProfilerTool getProfilerTool();
	public abstract IVOManager getVOManager(String domainID);
	public abstract IFeatureManager getFeatureManager();
}
